#include "proxymgrdlg.h"
#include "ui_proxymgrdlg.h"
#include "tdomain.h"
//#include "ctproxyrunnable.h"
#include "loadandvalidateproxytask.h"
//#include <QtNumeric>
#include "global.h"

ProxyMgrDlg::ProxyMgrDlg(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ProxyMgrDlg)
{
    ui->setupUi(this);
    m_tDomain = static_cast<TDomain *>(QWidget::parentWidget());
//    setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
//    setWindowModality(Qt::NonModal); // 设置为非模态对话框
    initUi();
    m_changeProxy = false;

    if(g_enableProxy)
        ui->checkBoxProxy->setChecked(true);
    else
        ui->checkBoxProxy->setChecked(false);

    for(int i=0;i<g_dataDicts.size();i++)
    {
        if(g_dataDicts[i].dd_key=="proxydest")
        {
            g_testProxyDest = g_dataDicts[i];
            break;
        }
    }
    if(g_testProxyDest.dd_key.length()==0)
        QMessageBox::information(this,"提示","没有找到测试代理目标");

}

ProxyMgrDlg::~ProxyMgrDlg()
{
    delete ui;
}

void ProxyMgrDlg::initUi()
{

    m_tableModel = new QStandardItemModel;
    QStringList strColsName;
    strColsName<<"代理服务器"<<"代理类型"<<"最新更新时间"<<"返回值";
    m_tableModel->setHorizontalHeaderLabels(strColsName);
    //QFont headerFont("Arial", 10, QFont::Bold);
    //ui->tableView->horizontalHeader()->setFont(headerFont);
    //ui->tableWidget->verticalHeader()->setFont(headerFont);
    ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section { background-color: lightgray; }");
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    //ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    // 设置行高
    ui->tableView->verticalHeader()->setDefaultSectionSize(30);
    // 禁止用户编辑单元格内容
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableView->setModel(m_tableModel);
    // 自动调整列宽
    ui->tableView->resizeColumnsToContents();
    ui->progressBar->setRange(0,100);
    ui->progressBar->setValue(0);
    ui->btn_stopCheck->setEnabled(false);
    m_selectProxyServer.clear();
    m_selectProxyServer = m_tDomain->m_dbMySql->getProxyServers(0);
    refleshTable(m_selectProxyServer);
}
void ProxyMgrDlg::refleshTable(QVector<ProxyServerData> qvpsd)
{
    m_tableModel->removeRows(0,m_tableModel->rowCount());
    //m_allProxyServer = qvpsd;//m_tDomain->m_dbMySql->getProxyServers(proxyFlag);
    m_progressBarTotal=m_selectProxyServer.size();

    int rowidx=0;
//    g_proxyPool.proxies.clear();
    foreach (auto psd, m_selectProxyServer) {

        QList<QStandardItem *> rowItems ;
        rowItems.append(new QStandardItem(psd.proxyaddr));
        //rowItems.append(new QStandardItem(psd.port));
        rowItems.append(new QStandardItem(psd.proxytype));
        rowItems.append(new QStandardItem(psd.updatedatetime));
        rowItems.append(new QStandardItem(psd.statusStr));
        m_tableModel->appendRow(rowItems);

        rowidx++;
//        if(psd.isvalidity==1)
//        {
//            g_proxyPool.proxies.append(psd.proxyaddr);
//        }
//        if(rowidx>1)
//            break;
    }
    ui->tableView->resizeColumnsToContents();
}

void ProxyMgrDlg::startCheckProxy(QVector<ProxyServerData> qvpsd)
{
    ui->plainTextEdit->clear();
    m_progressBarCurrent = 0;
    m_progressBarTotal =qvpsd.size();
    ui->progressBar->setValue(0);
    qDebug()<<"startCheckProxy"<<m_progressBarTotal;
    //return;
    // 启动后台线程来处理代理列表加载和任务发起
    auto loadAndValidateProxyTask = new LoadAndValidateProxyTask(qvpsd);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::started, this, [this](QString proxy) {
        qDebug()<<"开始检测代理"<<proxy;
        QString str ="开始检测代理"+proxy;
        ui->plainTextEdit->appendPlainText(str);
    });
    //connect(loadAndValidateTask, &LoadAndValidateProxyTask::progress, this, &ProxyMgrDlg::onProgress);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::result, this, &ProxyMgrDlg::onRecvProxyStatus);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::finished, this, [this]() {
        qDebug()<<" 完成线程LoadAndValidateProxyTask，全部验证完毕，关闭等待提示或进行其他收尾操作";
    });

    QThread* taskThread = new QThread();
    loadAndValidateProxyTask->moveToThread(taskThread);
    connect(taskThread, &QThread::started, loadAndValidateProxyTask, &LoadAndValidateProxyTask::run);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::taskFinish, loadAndValidateProxyTask, &QObject::deleteLater);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::taskInterrupt, loadAndValidateProxyTask, &QObject::deleteLater);
    connect(loadAndValidateProxyTask, &QObject::destroyed, taskThread, &QThread::quit);
    connect(taskThread, &QThread::finished, taskThread, &QThread::deleteLater);
    connect(this, &ProxyMgrDlg::stopThread, loadAndValidateProxyTask, &LoadAndValidateProxyTask::stopThread);
    taskThread->start();
    m_changeProxy = true;
}

void ProxyMgrDlg::on_btn_checkProxy_clicked()
{
    ui->btn_updateProxy->setEnabled(false);
    ui->btn_checkProxy->setEnabled(false);
    ui->btn_delProxy->setEnabled(false);
    ui->btn_stopCheck->setEnabled(true);

    //startCheckProxy(m_selectProxyServer);
    ui->plainTextEdit->clear();
    m_progressBarCurrent = 0;
    m_progressBarTotal =m_selectProxyServer.size();
    ui->progressBar->setValue(0);
    qDebug()<<"startCheckProxy"<<m_progressBarTotal;

    auto loadAndValidateProxyTask = new LoadAndValidateProxyTask(m_selectProxyServer);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::started, this, [this](QString proxy) {
        qDebug()<<"开始检测代理"<<proxy;
        QString str ="开始检测代理"+proxy;
        ui->plainTextEdit->appendPlainText(str);
    });
    QThread* taskThread = new QThread();
    loadAndValidateProxyTask->moveToThread(taskThread);

    connect(taskThread, &QThread::started, loadAndValidateProxyTask, &LoadAndValidateProxyTask::run);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::destroyed, taskThread, &QThread::quit);
    connect(taskThread, &QThread::finished, taskThread, &QThread::deleteLater);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::result,this, &ProxyMgrDlg::onRecvProxyStatus);
    connect(loadAndValidateProxyTask, &LoadAndValidateProxyTask::taskInterrupt,this, &ProxyMgrDlg::taskInterruptDeal);
    connect(this, &ProxyMgrDlg::stopThread, this, [this, loadAndValidateProxyTask]() {
        loadAndValidateProxyTask->stopThread();
    });
    taskThread->start();
    m_changeProxy = true;
}

void ProxyMgrDlg::on_btn_updateProxy_clicked()
{
    ui->btn_updateProxy->setEnabled(false);
    ui->btn_checkProxy->setEnabled(false);
    ui->btn_delProxy->setEnabled(false);
    ui->btn_stopCheck->setEnabled(false);
    ui->plainTextEdit->clear();
    QNetworkAccessManager* manager = new QNetworkAccessManager();
    // 设置目标 URL
    QUrl url("https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt");
    ui->plainTextEdit->appendPlainText("开始请求代理列表");
    // 发起 GET 请求
    QNetworkReply* reply = manager->get(QNetworkRequest(url));
    // 连接完成信号和错误信号
    QObject::connect(reply, &QNetworkReply::finished, [=]() {

        if (reply->error() == QNetworkReply::NoError) {
            // 请求成功，读取并保存响应数据到文件
            // 使用 QTextStream 解析字节数组中的文本数据
            qDebug()<<"请求代理服务器列表成功";
            ui->plainTextEdit->appendPlainText("获取代理服务器列表成功");
            QTextStream textStream(reply->readAll());
            // 逐行读取并添加到 lines 列表中
            //QList<QString> proxies;
            QString proxyStr;
            QVector<ProxyServerData> allProxyServer;

            int num =0;
            while (!textStream.atEnd()) {
                proxyStr = textStream.readLine();
//                QStringList stringList = proxyStr.split(":");
                ProxyServerData psd;
//                psd.serveraddr = stringList.at(0);
//                psd.port = stringList.at(1);
                psd.proxyaddr = proxyStr;
                psd.testproxydest = m_testProxyDest.dd_values;
                QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
                psd.updatedatetime = strDateTime;
                allProxyServer.append(psd);
                num++;

                ui->plainTextEdit->appendPlainText("获取代理:"+proxyStr);
            }
            if(allProxyServer.length())
            {
                m_tDomain->m_dbMySql->updateProxyServerTable(allProxyServer);
                qDebug()<<"代理服务器列表更新数据库成功";
            }
        } else {
            qDebug() << "Error downloading SOCKS5 list: " << reply->errorString();
            QMessageBox::information(this,"提示","更新代理失败");
            ui->btn_updateProxy->setEnabled(true);
            ui->btn_checkProxy->setEnabled(true);
            ui->btn_delProxy->setEnabled(true);
            ui->btn_stopCheck->setEnabled(false);
            return;
        }

        // 清理资源
        reply->deleteLater();
        manager->deleteLater();

        ui->btn_updateProxy->setEnabled(true);
        ui->btn_checkProxy->setEnabled(true);
        ui->btn_delProxy->setEnabled(true);
        ui->btn_stopCheck->setEnabled(false);
        m_selectProxyServer.clear();
        m_selectProxyServer = m_tDomain->m_dbMySql->getProxyServers(0);
        refleshTable(m_selectProxyServer);
        // QVector<ProxyServerData> qvps = m_tDomain->m_dbMySql->getProxyServers(0);
        // refleshTable(qvps);
        qDebug()<<"刷新代理服务器列表成功";
        QMessageBox::information(this,"提示","更新代理成功");
    });

    // 连接网络错误信号
    QObject::connect(reply, &QNetworkReply::errorOccurred, [](QNetworkReply::NetworkError error) {
        qDebug() << "Network error occurred while downloading SOCKS5 list: " << error;
    });

}

void ProxyMgrDlg::dataReceivedFromSocket(const QByteArray data, const QString requestParam)
{
    qDebug()<<"dataReceivedFromSocket"<<requestParam<<data.length();
    // emit resultReady(data,requestParam);
}

void ProxyMgrDlg::onRecvProxyStatus(const QString &validatedProxy,QString retStr)
{
    QString str = "代理:"+validatedProxy+",返回结果:"+retStr;
    ui->plainTextEdit->appendPlainText(str);
    m_progressBarCurrent++;
    float fraction =100* m_progressBarCurrent / m_progressBarTotal;
    int prvalue =  qRound(fraction);

    //qDebug() << "代理"<<validatedProxy<<"返回信息:"<<retStr;//<<m_progressBarCurrent<<m_progressBarTotal;
    ui->progressBar->setValue(prvalue);
    //根据flag匹配m_tableModel中的记录
    QString proxyHost=validatedProxy;//.left(validatedProxy.indexOf(':'));

    QList<QStandardItem*> foundLst = m_tableModel->findItems(proxyHost, Qt::MatchExactly, 0);
    if(foundLst.size()<1)
    {
        qDebug() << "找不到指定的域名信息" << proxyHost;
        return;
    }
    QStandardItem* item = foundLst.at(0);
    int row = item->row();
    QString proxyStatus = retStr;
    m_tableModel->item(row,3)->setText(proxyStatus);
    QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    m_tDomain->m_dbMySql->updateProxyServerStatus(proxyHost,strDateTime,proxyStatus);
    if(prvalue==100)
    {
        ui->btn_updateProxy->setEnabled(true);
        ui->btn_checkProxy->setEnabled(true);
        ui->btn_delProxy->setEnabled(true);
        ui->btn_stopCheck->setEnabled(false);
    }
}

void ProxyMgrDlg::onFinished(QNetworkReply *reply)
{
    if (reply->error() == QNetworkReply::NoError) {
        QByteArray data = reply->readAll();
        QString response(data);
        if (!response.isEmpty()) {
            qDebug() << "代理服务器可用。来自example.com的响应:" << response;
        } else {
            qDebug() << "从example.com收到空响应";
        }
    } else {
        qDebug() << "代理服务器不可用或发生错误：" << reply->errorString();
    }
    reply->deleteLater();
}

void ProxyMgrDlg::on_btn_delProxy_clicked()
{
    QMessageBox::StandardButton result= QMessageBox::question(this,"提示","确认要删除无效的代理？");
    if(result==QMessageBox::Yes)
    {
        m_tDomain->m_dbMySql->deleteInvalidProxy();

        QVector<ProxyServerData> qvps = m_tDomain->m_dbMySql->getProxyServers(0);
        refleshTable(qvps);
    }
}


void ProxyMgrDlg::on_btn_stopCheck_clicked()
{
     ui->plainTextEdit->appendPlainText("处理正在退出，请稍后...");
    emit stopThread();
}

void ProxyMgrDlg::on_btn_close_clicked()
{
    if(ui->btn_stopCheck->isEnabled())
    {
        QMessageBox::information(this,"提示","请先停止代理验证");
        return;
    }else{
        if(m_changeProxy)
        {
            qDebug()<<"更新全局代理服务器池";
            QVector<ProxyServerData> vpsd = m_tDomain->m_dbMySql->getProxyServers(1);
            g_proxyPool.proxies.clear();

            foreach (auto pd, vpsd) {
                g_proxyPool.proxies.append(pd.proxyaddr);
            }
            qDebug()<<"proxypool size"<<g_proxyPool.proxies.size();
        }
        this->close();
    }

    if(ui->checkBoxProxy->isChecked())
        g_enableProxy= true;
    else
        g_enableProxy= false;

}


void ProxyMgrDlg::on_cb_proxyStatus_currentTextChanged(const QString &arg1)
{
    //QString proxyStatus = ui->cb_proxyStatus->currentText();
    //qDebug()<<proxyStatus<<arg1;
    m_selectProxyServer.clear();
    if(arg1=="全部代理"){
        m_selectProxyServer= m_tDomain->m_dbMySql->getProxyServers(0);
    }else if(arg1=="有效代理"){
        m_selectProxyServer= m_tDomain->m_dbMySql->getProxyServers(1);
    }else if(arg1=="无效代理"){
        m_selectProxyServer= m_tDomain->m_dbMySql->getProxyServers(2);
    }else{//"未验证代理"
        m_selectProxyServer= m_tDomain->m_dbMySql->getProxyServers(3);
    }
    refleshTable(m_selectProxyServer);
}

void ProxyMgrDlg::taskInterruptDeal() {
    ui->btn_updateProxy->setEnabled(true);
    ui->btn_checkProxy->setEnabled(true);
    ui->btn_delProxy->setEnabled(true);
    ui->btn_stopCheck->setEnabled(false);
     ui->plainTextEdit->appendPlainText("处理已退出");
}

void ProxyMgrDlg::on_pbt_testProxyDest_clicked() {

    bool ok;
    QString newText = QInputDialog::getText(this,"编辑测试代理目标","请输入新的代理目标地址:",QLineEdit::Normal,g_testProxyDest.dd_values,&ok);
    if (ok && !newText.isEmpty())
    {
        g_testProxyDest.dd_values = newText;
        m_tDomain->m_dbMySql->updateDataDict(g_testProxyDest.dd_key, g_testProxyDest);
        for(int i=0;i<g_dataDicts.size();i++)
        {
            if(g_dataDicts[i].dd_key=="proxydest")
            {
                g_dataDicts[i].dd_values = newText;
                break;
            }
        }
    }
}
